package com.uzhie.web.service;

import com.google.common.base.Strings;
import com.uzhie.exception.UserException;
import com.uzhie.util.ConstantKit;
import com.uzhie.util.TreeUtil;
import com.uzhie.web.dao.*;
import com.uzhie.web.module.*;
import org.apache.ibatis.session.RowBounds;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 用户service,封装与用户相关的服务操作
 * <p>
 * Created by lilongfei on 2018/7/12.
 */
@Service
public class UserService {

    @Autowired
    private UserDAO userDAO;
    @Autowired
    private RoleDAO roleDAO;
    @Autowired
    private MenuDAO menuDAO;
    @Autowired
    private UserCatalogDAO userCatalogDAO;
    @Autowired
    private CatalogDAO catalogDAO;


    // 用户状态集合 , 0  删除, 1 启用 , 2 禁用
    private Integer[] types = new Integer[]{ConstantKit.STATUS.DELETED,
            ConstantKit.STATUS.IS_AVAILABLE, ConstantKit.STATUS.UN_AVAILABLE};

    /**
     * 用户登录服务,查询当前用户登录是否合法,如果用户登录合法,则获取当前用户登录信息,角色信息,权限信息,并打包为
     * jsonObject对象返回
     *
     * @param userName
     * @param pwd
     * @return
     */
    public User userLogin(String userName, String pwd) throws UserException {
//        if (userName != null && userName.length() >= 6 && userName.length() <= 18)
//                if (pwd != null && pwd.length() >= 6 && pwd.length() <= 18) {
//                pwd = Tools.EncoderByMd5(pwd);
        User t_user = userDAO.findByNameAndPwd(userName, pwd);
        if (t_user != null) {
            //获取用户角色信息
            List<Role> roles = roleDAO.findRoleByUserID(t_user.getId());
            if (roles == null || roles.size() == 0) throw new UserException(UserException.Status.NO_ROLES);
            t_user.setRoles(roles);
            //获取用户角色菜单
            List<Menu> t_menus = menuDAO.findMenuByUserId(t_user.getId());
            if (t_menus == null || t_menus.size() == 0) throw new UserException(UserException.Status.NO_POWER);
            //对用户权限菜单进行树状拼接,并生成JSONARRAY对象
            List<Menu> menu = null;
            try {
                menu = new TreeUtil(t_menus).buildTree();
            } catch (Exception e) {
                e.printStackTrace();
                throw new UserException(UserException.Status.POWER_ERROR);
            }
            t_user.setMenus(menu.get(0));
            return t_user;
        }

//            }

        throw new UserException(UserException.Status.PWD_ERROR);
    }

    /**
     * 新增用户,并同时绑定用户与车辆的数据权限关系
     * 新增用户时前端需传递用户ID,但是可以随便写一个值,该值不会保存在数据库中
     *
     * @param user 用户对象
     * @throws UserException 业务异常
     */
    public void addUser(@NotNull(message = UserException.Status.USER_ISNULL) @Valid User user) throws UserException {
        //对人员数据进行判空操作
        if (user.getUsername() == null) throw new UserException(UserException.Status.USERNAME_ISNULL);
        if (user.getPassword() == null) throw new UserException(UserException.Status.PWD_ISNULL);
        if (user.getName() == null) throw new UserException(UserException.Status.REALNAME_ISNULL);
        //更新新增时间为服务器时间
        user.setCreateTime(new Date());
//        user.setPassword(Tools.EncoderByMd5(user.getPassword()));
        //设置用户状态
        user.setStatus(ConstantKit.STATUS.IS_AVAILABLE);
        try {
            //插入人员信息,并获取返回的userId
            userDAO.insert(user);
        } catch (Exception e) {
            throw new UserException(UserException.Status.NAME_EXIST);
        }
    }

    /**
     * 更新用户状态
     *
     * @param user   需要更新的用户对象
     * @param status 需要更新的用户状态
     * @return
     * @throws UserException
     */
    public void updateUserStatus(@NotEmpty(message = UserException.Status.USER_ISNULL) User user,
                                 int status) throws UserException {

        List<Integer> arr = Arrays.asList(types);
        if (!arr.contains(status)) throw new UserException(UserException.Status.STATUS_ERROR);
        if (status == 2 && user.getStatus() != 1) throw new UserException(UserException.Status.CANT_DELETE);
        user.setUpdateTime(new Date());
        userDAO.updateStatusByUserId(user.getId(), status);
    }

    /**
     * 批量更新用户状态
     *
     * @param users  需要更新的用户id集合
     * @param status 用户状态代码 0 删除 1 启用 2 禁用
     * @throws UserException
     */
    public void updateUserStatusByList(@NotNull(message = UserException.Status.USER_ISNULL) List<User> users, int status) throws UserException {
        List<Integer> arr = Arrays.asList(types);
        if (users.size() == 0) throw new UserException(UserException.Status.USER_ISNULL);
        if (!arr.contains(status)) throw new UserException(UserException.Status.STATUS_ERROR);
        for (User user : users) {
            if (Strings.isNullOrEmpty(user.getId())) throw new UserException(UserException.Status.ID_ISNULL);
            if (status == 0) {
                if (user.getStatus() != null && user.getStatus() != 2)
                    throw new UserException(UserException.Status.CANT_DELETE);
                user.setUpdateTime(new Date());
                userDAO.deleteByPrimaryKey(user.getId());
            }
        }
        if (status != 0)
            userDAO.updateStatusByUserIds(users, status);
    }

    /**
     * 修改用户属性
     *
     * @param user
     */
    public void updateUser(@NotNull(message = UserException.Status.USER_ISNULL) @Valid User user) {
        userDAO.updateByPrimaryKey(user);
    }

    /**
     * 绑定目录与用户关系
     *
     * @param userId
     * @return
     * @throws UserException
     */
    public void bindVehicle(@NotEmpty(message = UserException.Status.ID_ISNULL) String userId, String userName, List<Catalog> vhs) throws UserException {
        //清除当前用车辆关系
        userCatalogDAO.unbindUserCatalog(userId);
        if (vhs != null && vhs.size() > 0) {
            //绑定车辆与人员的中间关系
            List<UserCatalog> bindContents = UserCatalog.getListById(vhs, userId, userName);
            //插入人员与车辆关系
            userCatalogDAO.bindUserCatalog(bindContents);
        }
    }

    /**
     * 绑定用户与角色关系,用户角色为多对多关系绑定
     *
     * @param userId   需要绑定的用户Id
     * @param userName 需要绑定的用户名称
     * @param roles    绑定的角色集合
     * @throws UserException 如果用户id为空,或绑定的角色集合为空,或角色集合内的角色对象存在参数问题,则抛出异常信息
     */
    public void bindRole(@NotEmpty(message = UserException.Status.ID_ISNULL) String userId, String userName, @Valid List<Role> roles) throws UserException {
        if (roles == null || roles.size() == 0) throw new UserException(UserException.Status.NO_ROLES);
        List<UserRole> urs = UserRole.getListByRoleId(userId, userName, roles);
        userDAO.unBindUserRoles(userId);
        userDAO.bindUserRoles(urs);
    }

    /**
     * 用户查询方法,查询方法用户的是模糊查询
     *
     * @param userName  用户名称
     * @param realName  用户真实姓名
     * @param deptName  部门名称
     * @param roleName  角色名称
     * @param startTime 创建时间范围查询: 起始时间
     * @param endTime   创建时间范围查询: 结束时间
     * @param page      分页功能
     * @return 用户列表
     */
    public List<User> queryUserList(@NotEmpty(message = UserException.Status.DEPT_ISNULL) String departId, String userName, String realName, String deptName, String roleName, String startTime, String endTime, RowBounds page) throws UserException {
        List<Catalog> catalogs = catalogDAO.selectCatalogByUserDepart(departId);
        List<String> departIds = new ArrayList<>();
        for (Catalog catalog : catalogs) {
            departIds.add(catalog.getId());
        }
        if (departIds == null) throw new UserException(UserException.Status.QUERY_STATUS_ERROR);
        List<User> users = userDAO.queryUserList(departIds, userName, realName, deptName, roleName, startTime, endTime, page);
        return users;
    }

    /**
     * 通过用户ID获取用户对象
     *
     * @param userId 用户id
     * @return
     */
    public User findUserById(@NotEmpty(message = UserException.Status.ID_ISNULL) String userId) {
        return userDAO.selectByPrimaryKey(userId);
    }

    /**
     * 修改用户密码
     *
     * @param userId
     * @param oldPwd
     * @param pwd
     * @throws UserException
     */
    public void updatePassword(@NotEmpty(message = UserException.Status.ID_ISNULL) String userId,
                               @NotEmpty(message = UserException.Status.PWD_ISNULL) String oldPwd,
                               @NotEmpty(message = UserException.Status.PWD_ISNULL) String pwd) throws UserException {
        User user = findUserById(userId);
        if (user == null) throw new UserException(UserException.Status.STATUS_ERROR);
        if (!oldPwd.equals(user.getPassword())) {
            throw new UserException(UserException.Status.OLD_PWD_ERROR);
        }
        user.setPassword(pwd);
        userDAO.updateByPrimaryKeySelective(user);
    }
}


